package com.tom.springframework.beans.factory.support;

import com.tom.springframework.BeansException;
import com.tom.springframework.beans.factory.BeanFactory;
import com.tom.springframework.beans.factory.config.BeanDefinition;

/**
 * 抽象Bean 工厂基类，定义模板方法
 * <pre>
 * 同时具有注册单例Bean 对象功能。
 * 定义模板方法:
 *     1.先从单例池中获取对象，
 *     2.如果没有获取到。需要根据beanDefinition 创建对象，再放入单例池中。
 *      2.1 beanDefinition 和单例池一样，需要定义一个BeanDefinition注册接口
 *      2.2 如果单例池中没有获取到单例对象，需要先重BeanDefinition注册中获取对应的BeanDefinition 信息
 *      2.3 根据BeanDefinition 创建对象，然后放入到单例池中
 *
 *
 * </pre>
 * @author zx
 * @date 2024-11-05 10:01
 */
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {

    @Override
    public Object getBean(String name)throws BeansException{
        return doGetBean(name,null);
    }

    @Override
    public Object getBean(String name, Object... args) throws BeansException {
        return doGetBean(name,args);
    }


    public <T> T doGetBean(String name,final Object[] args) throws BeansException {
        Object bean = getSingleton(name);
        if(bean !=null){
            return (T) bean;
        }
        //当单例Bean 池中如果没有, 从BeanDefinition注册表中根据Bean 名称获取对应的BeanDefinition信息
        //获取到BeanDefinition信息后，创建对象，然后放入到单例池中
        BeanDefinition beanDefinition = getBeanDefinition(name);
        return (T)createBean(name,beanDefinition,args);
    }

    protected abstract Object createBean(String beanName,BeanDefinition beanDefinition,Object[] args) ;

    protected abstract BeanDefinition getBeanDefinition(String name) ;


}
